/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core/memory
// Copyright (c) 2014.  All Rights Reserved
//
// File:		AEContainerHeapAllocator.h
// Author:		Gianluca Belardelli
// Date:		27/05/2014
//
/////////////////////////////////////////////////////////////////////////
#include <AECore.h>

AEContainerHeapAllocator::AEAllocator AEContainerHeapAllocator::ms_aAllocator;
AEContainerDebugAllocator::AEAllocator AEContainerDebugAllocator::ms_aAllocator;
AEContainerTempAllocator::AEAllocator AEContainerTempAllocator::ms_aAllocator;

#define DEFAULT_BLOCK_INCREMENT		128

void *AEContainerHeapAllocator::AEAllocator::BlockAlloc( AEUINT32 uiNumBytes, AEMemoryAlign maAlign )
{
	if( uiNumBytes < DEFAULT_BLOCK_INCREMENT )
		uiNumBytes = DEFAULT_BLOCK_INCREMENT;
	else
		uiNumBytes += DEFAULT_BLOCK_INCREMENT;

	return AEMemoryManager::GetInstance().GetHeapAllocator().BlockAlloc( uiNumBytes );
}

void AEContainerHeapAllocator::AEAllocator::BlockFree( void *lpPtr, AEUINT32 uiNumBytes )
{
}

void *AEContainerHeapAllocator::AEAllocator::BufAlloc( AEINT32 &nReqNumBytesInOut )
{
	if( nReqNumBytesInOut < DEFAULT_BLOCK_INCREMENT )
		nReqNumBytesInOut = DEFAULT_BLOCK_INCREMENT;
	else
		nReqNumBytesInOut += DEFAULT_BLOCK_INCREMENT;

	return AEMemoryManager::GetInstance().GetHeapAllocator().BlockAlloc( nReqNumBytesInOut );
	//return (void *)new char[ nReqNumBytesInOut ];
}

void AEContainerHeapAllocator::AEAllocator::BufFree( void *lpPtr, AEINT32 nNumBytes )
{
}

void *AEContainerHeapAllocator::AEAllocator::BufRealloc( void *lpOldPtr, AEINT32 nOldNumBytes, AEINT32 &nReqNumBytesInOut )
{
	if( nReqNumBytesInOut < DEFAULT_BLOCK_INCREMENT )
		nReqNumBytesInOut = DEFAULT_BLOCK_INCREMENT;
	else
		nReqNumBytesInOut += DEFAULT_BLOCK_INCREMENT;

	void *lpNewPtr = BlockAlloc( nReqNumBytesInOut );
	memcpy( lpNewPtr, lpOldPtr, nOldNumBytes );

	BlockFree( lpOldPtr, nOldNumBytes );
	//delete lpOldPtr;

	return lpNewPtr;
}

void AEContainerHeapAllocator::AEAllocator::GetMemoryStats( AEMemStats &msStats )
{
}

AEINT32 AEContainerHeapAllocator::AEAllocator::GetAllocatedSize( const void *lpObj, AEINT32 nBytes )
{
	return AEMemoryManager::GetInstance().GetHeapAllocator().GetAllocatedSize( lpObj, nBytes );
}




void *AEContainerDebugAllocator::AEAllocator::BlockAlloc( AEUINT32 uiNumBytes, AEMemoryAlign maAlign )
{
	if( uiNumBytes < DEFAULT_BLOCK_INCREMENT )
		uiNumBytes = DEFAULT_BLOCK_INCREMENT;
	else
		uiNumBytes += DEFAULT_BLOCK_INCREMENT;

	return AEMemoryManager::GetInstance().GetHeapAllocator().BlockAlloc( uiNumBytes );
}

void AEContainerDebugAllocator::AEAllocator::BlockFree( void *lpPtr, AEUINT32 uiNumBytes )
{
}

void *AEContainerDebugAllocator::AEAllocator::BufAlloc( AEINT32 &nReqNumBytesInOut )
{
	if( nReqNumBytesInOut < DEFAULT_BLOCK_INCREMENT )
		nReqNumBytesInOut = DEFAULT_BLOCK_INCREMENT;
	else
		nReqNumBytesInOut += DEFAULT_BLOCK_INCREMENT;

	return AEMemoryManager::GetInstance().GetHeapAllocator().BlockAlloc( nReqNumBytesInOut );
	//return (void *)new char[ nReqNumBytesInOut ];
}

void AEContainerDebugAllocator::AEAllocator::BufFree( void *lpPtr, AEINT32 nNumBytes )
{
}

void *AEContainerDebugAllocator::AEAllocator::BufRealloc( void *lpOldPtr, AEINT32 nOldNumBytes, AEINT32 &nReqNumBytesInOut )
{
	if( nReqNumBytesInOut < DEFAULT_BLOCK_INCREMENT )
		nReqNumBytesInOut = DEFAULT_BLOCK_INCREMENT;
	else
		nReqNumBytesInOut += DEFAULT_BLOCK_INCREMENT;

	void *lpNewPtr = BlockAlloc( nReqNumBytesInOut );
	memcpy( lpNewPtr, lpOldPtr, nOldNumBytes );

	BlockFree( lpOldPtr, nOldNumBytes );
	//delete lpOldPtr;

	return lpNewPtr;
}

void AEContainerDebugAllocator::AEAllocator::GetMemoryStats( AEMemStats &msStats )
{
}

AEINT32 AEContainerDebugAllocator::AEAllocator::GetAllocatedSize( const void *lpObj, AEINT32 nBytes )
{
	return AEMemoryManager::GetInstance().GetHeapAllocator().GetAllocatedSize( lpObj, nBytes );
}




void *AEContainerTempAllocator::AEAllocator::BlockAlloc( AEUINT32 uiNumBytes, AEMemoryAlign maAlign )
{
	if( uiNumBytes < DEFAULT_BLOCK_INCREMENT )
		uiNumBytes = DEFAULT_BLOCK_INCREMENT;
	else
		uiNumBytes += DEFAULT_BLOCK_INCREMENT;

	return AEMemoryManager::GetInstance().GetHeapAllocator().BlockAlloc( uiNumBytes );
}

void AEContainerTempAllocator::AEAllocator::BlockFree( void *lpPtr, AEUINT32 uiNumBytes )
{
}

void *AEContainerTempAllocator::AEAllocator::BufAlloc( AEINT32 &nReqNumBytesInOut )
{
	if( nReqNumBytesInOut < DEFAULT_BLOCK_INCREMENT )
		nReqNumBytesInOut = DEFAULT_BLOCK_INCREMENT;
	else
		nReqNumBytesInOut += DEFAULT_BLOCK_INCREMENT;

	return AEMemoryManager::GetInstance().GetHeapAllocator().BlockAlloc( nReqNumBytesInOut );
	//return (void *)new char[ nReqNumBytesInOut ];
}

void AEContainerTempAllocator::AEAllocator::BufFree( void *lpPtr, AEINT32 nNumBytes )
{
}

void *AEContainerTempAllocator::AEAllocator::BufRealloc( void *lpOldPtr, AEINT32 nOldNumBytes, AEINT32 &nReqNumBytesInOut )
{
	if( nReqNumBytesInOut < DEFAULT_BLOCK_INCREMENT )
		nReqNumBytesInOut = DEFAULT_BLOCK_INCREMENT;
	else
		nReqNumBytesInOut += DEFAULT_BLOCK_INCREMENT;

	void *lpNewPtr = BlockAlloc( nReqNumBytesInOut );
	memcpy( lpNewPtr, lpOldPtr, nOldNumBytes );

	BlockFree( lpOldPtr, nOldNumBytes );
	//delete lpOldPtr;

	return lpNewPtr;
}

void AEContainerTempAllocator::AEAllocator::GetMemoryStats( AEMemStats &msStats )
{
}

AEINT32 AEContainerTempAllocator::AEAllocator::GetAllocatedSize( const void *lpObj, AEINT32 nBytes )
{
	return AEMemoryManager::GetInstance().GetHeapAllocator().GetAllocatedSize( lpObj, nBytes );
}
